import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

// 界面层
public class CheeseBoard extends JPanel {
    // 记录棋子的坐标
    private Coordinate[][] c;
    // 记录棋子被选中范围以及被选中状态的二维数组（被选中状态：是否被选，被谁选）
    private CheeseStragy.Cheese[][] cheeses;
    // 记录获胜玩家
    private CheeseStragy.Role winner = CheeseStragy.Role.NONE;

    public CheeseBoard(){
        super();
        init();
    }

    // 坐标
    class Coordinate {
        int x, y;
        Coordinate(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    void init(){
        c = new Coordinate[][]{
                {new Coordinate(80,50),new Coordinate(190,50), new Coordinate(300,50)},
                {new Coordinate(135, 140),new Coordinate(190, 140), new Coordinate(245, 140)},
                {null,new Coordinate(190, 230), null},
                {new Coordinate(135, 320),new Coordinate(190, 320), new Coordinate(245, 320)},
                {new Coordinate(80, 410),new Coordinate(190, 410), new Coordinate(300, 410)},
        };
        // 初始化棋盘上的棋子位置
        CheeseStragy.instance.initCheeses();
        // 获取棋盘上的棋子
        cheeses = CheeseStragy.instance.getCheeses();
        // 初始化棋盘棋子位置大小形状
        initCheesesCoordinate();

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                setCursor(new Cursor(Cursor.HAND_CURSOR));  // 手形鼠标
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); // 默认鼠标
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                // 选择的棋子坐标
                CheeseStragy.Cheese whichCheese = getCheese(e.getX(), e.getY());
                if (whichCheese != null) {
                    // 标志选中
                    CheeseStragy.instance.setCheeseSelected(whichCheese.y, whichCheese.x);
                    // 控制台输出哪颗棋子被选中
                    System.out.println(whichCheese.selected + " clicked!" );
                    if (whichCheese.selected) {
                        CheeseStragy.instance.getAvaliablePostion(whichCheese);
                    }
                } else {
                    // 如果选中的地方没有棋子 则说明是落子的位置
                    ArrayList positions = CheeseStragy.instance.getAvaliablePostion();
                    // 获得落子的位置，通过遍历棋盘上所有可行的位置获得（小圆点）
                    CheeseStragy.P p = getP(positions, e.getX(), e.getY());
                    if (p != null) {
                        // 如果落点合理，则将棋子落在该处
                        CheeseStragy.instance.goTargetPosition(CheeseStragy.instance.getCheese(positions), p, c);
                    }
                }
                // 判断赢家
                winner = judgeWhichWin();

                // 重绘棋盘 实质是调用paintComponent()
                repaint();
            }
            
            private CheeseStragy.P getP(ArrayList<CheeseStragy.P> avaliablePostion, int x_, int y_) {
                for (CheeseStragy.P p: avaliablePostion ) {
                    Rectangle rect = new Rectangle(new Rectangle(c[p.y][p.x].x - 5, c[p.y][p.x].y - 5, 20, 20));
                    if (rect.contains(x_, y_)){
                        // 因为一次最多只会越过一个棋子，所以找到便返回
                        return p;
                    }
                }
                return null;
            }
        });
    }
    // 初始化棋子的坐标
    private void initCheesesCoordinate() {
        for(int y = 0; y < cheeses.length; y++) {
            for (int x = 0; x < cheeses[0].length; x++) {
                if(cheeses[y][x] != null) {
                    cheeses[y][x].rect = new Rectangle(c[y][x].x - 5 , c[y][x].y - 5,20,20);
                }
            }
        }
    }
    // 绘制组件（棋盘、棋子、赢家（可能）），每次落子后都绘制一遍
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawBoard(g);
        drawCheese(g);
        if(winner != CheeseStragy.Role.NONE) {
            drawWinnder(g);
        }
    }

    // 绘制胜方
    private void drawWinnder(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.RED);
        g2d.setFont(new Font("Serif", Font.ITALIC, 24));
        g2d.drawString(winner == CheeseStragy.Role.RED ? "红方胜!" : "黑方胜!" , 150, 250);
    }
    
    // 画棋盘
    private void drawBoard(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g.setColor(Color.lightGray);
        //画点
        g2d.fillOval(c[0][0].x, c[0][0].y,10,10);
        g2d.fillOval(c[0][1].x, c[0][1].y,10,10);
        g2d.fillOval(c[0][2].x, c[0][2].y,10,10);

        g2d.fillOval(c[1][0].x, c[1][0].y,10,10);
        g2d.fillOval(c[1][1].x, c[1][1].y,10,10);
        g2d.fillOval(c[1][2].x, c[1][2].y,10,10);

        g2d.fillOval(c[2][1].x, c[2][1].y,10,10);

        g2d.fillOval(c[3][0].x, c[3][0].y,10,10);
        g2d.fillOval(c[3][1].x, c[3][1].y,10,10);
        g2d.fillOval(c[3][2].x, c[3][2].y,10,10);

        g2d.fillOval(c[4][0].x, c[4][0].y,10,10);
        g2d.fillOval(c[4][1].x, c[4][1].y,10,10);
        g2d.fillOval(c[4][2].x, c[4][2].y,10,10);

        //横线
        g2d.drawLine(c[0][0].x + 5, c[0][0].y + 5,c[0][2].x + 5, c[0][2].y + 5);
        g2d.drawLine(c[1][0].x + 5, c[1][0].y + 5,c[1][2].x + 5, c[1][2].y + 5);
        g2d.drawLine(c[3][0].x + 5, c[3][0].y + 5,c[3][2].x + 5, c[3][2].y + 5);
        g2d.drawLine(c[4][0].x + 5, c[4][0].y + 5,c[4][2].x + 5, c[4][2].y + 5);

        //竖线
        g2d.drawLine(c[0][1].x + 5, c[0][1].y + 5,c[4][1].x + 5, c[4][1].y + 5);

        //斜线
        g2d.drawLine(c[0][0].x + 5, c[0][0].y + 5,c[4][2].x + 5, c[4][2].y + 5);
        g2d.drawLine(c[0][2].x + 5, c[0][2].y + 5,c[4][0].x + 5, c[4][0].y + 5);
    }

    // 画棋子
    private void drawCheese(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        for(int y = 0; y < cheeses.length; y++) {
            for (int x = 0; x < cheeses[0].length; x++) {
                if(cheeses[y][x] != null) {
                    Color color = cheeses[y][x].role == CheeseStragy.Role.RED ? Color.RED: Color.BLACK;
                    g.setColor(color);
                    g2d.fillOval(cheeses[y][x].rect.x, cheeses[y][x].rect.y, cheeses[y][x].rect.width, cheeses[y][x].rect.height);
                    if (cheeses[y][x].selected) {
                        g2d.drawRect(cheeses[y][x].rect.x, cheeses[y][x].rect.y, cheeses[y][x].rect.width, cheeses[y][x].rect.height);
                    }
                }
            }
        }
    }

    
    CheeseStragy.Cheese getCheese(int px, int py){
        for(int y = 0; y < cheeses.length; y++) {
            for (int x = 0; x < cheeses[0].length; x++) {
                // 只要在棋子的大小范围中点中一个点就被算作选中棋子
                if (cheeses[y][x] != null && cheeses[y][x].rect.contains(px, py)) {
                    return cheeses[y][x];
                }
            }
        }
        return null;
    }

    // 输方棋子个数为0
    private CheeseStragy.Role judgeWhichWin() {
        int redLiving = 0, blackLiving = 0;
        for(int y = 0; y < cheeses.length; y++) {
            for (int x = 0; x < cheeses[0].length; x++) {
                if (cheeses[y][x] != null && cheeses[y][x].role == CheeseStragy.Role.RED)  ++redLiving;
                if (cheeses[y][x] != null && cheeses[y][x].role == CheeseStragy.Role.BLACK) ++blackLiving;
                if (redLiving != 0 && blackLiving != 0){
                    return CheeseStragy.Role.NONE;
                }
            }
        }
        return redLiving != 0 ? CheeseStragy.Role.RED : CheeseStragy.Role.BLACK;
    }
}
